from venv import logger

from pymongo import ReturnDocument

from ioservice.common.mongo import find_one_doc_and_update, insert_one_model, find_one_doc, update_docs, \
    delete_one_model
from ioservice.const import counter_col
from models.counter import Counter
from utils.dateutil import date_now


async def generate_object_code(model_counter):
    counter_name, prefix = model_counter.split('.')
    model_number = await get_new_counter_by_name(counter_name)
    return model_number, f"{prefix}{model_number}"


async def bulk_generate_object_code(model_counter, counter_num):
    counter_name, prefix = model_counter.split('.')
    model_number = await get_new_counter_by_name(counter_name, counter_num)
    ocodes = [(model_number - i, f"{prefix}{model_number - i}") for i in range(counter_num)]
    return ocodes


async def get_new_counter_by_name(counter_name, counter_num=1):
    query = {"name": counter_name}
    update = {"$inc": {"counter": counter_num}, "$set": {"update_time": date_now()}}
    res = await find_one_doc_and_update(counter_col, query, update, upsert=True,
                                        projection=["counter"], return_document=ReturnDocument.AFTER)
    return res["counter"]


# 目前没有用处的方法，后期酌情删除


async def get_one_counter_by_name(name, fields=None):
    res = await find_one_doc(counter_col, {"name": name}, projection=fields)
    return res


async def init_counter(name: str, counter: int = 0):
    # !!! 没有原子性，不建议使用
    exists = await get_one_counter_by_name(name, fields=["_id"])
    if exists:
        logger.error(f"counter: {name} already exists!")
        return False
    cur_time = date_now()
    counter = Counter(name=name, counter=counter, create_time=cur_time, update_time=cur_time)
    res = await insert_one_model(counter_col, counter)
    if res:
        logger.info(f"counter: {name} init success! {res}")
    return True


async def update_counter_by_name(counter_name, update):
    query = {"name": counter_name}
    res = await update_counter_by_query(query, update)
    return res


async def update_counter_by_query(query, update):
    res = await update_docs(counter_col, query, update)
    return res


async def delete_one_counter_by_name(counter_name):
    res = await delete_one_model(counter_col, query={"name":counter_name})
    return res